package ar.com.fiuba.domain.impl;

import ar.com.fiuba.application.impl.FileDataSource;
import ar.com.fiuba.domain.CommonCoeficientCalculationWithPositionStrategy;
import ar.com.fiuba.domain.Ngramm;
import ar.com.fiuba.domain.Word;

import java.io.IOException;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.TreeSet;

import com.mysql.jdbc.Connection;
import com.mysql.jdbc.Statement;

import ar.com.fiuba.domain.Dictionary;
import ar.com.fiuba.domain.exceptions.DomainException;

public class DictionaryImpl extends Dictionary{
	
	Connection con;
	private String filename;
	
	public String getFilename() {
		return filename;
	}
	
	public DictionaryImpl(String filename, int ngramLength, boolean createDB)
	{
		this.filename=filename;
		this.ngramLength = ngramLength;
		connectToDataBase();
		if(createDB)
		{	
			try{
				this.loadDataBase();
			}
			catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}	
	}

	private void connectToDataBase()
	{
			try{
				Class.forName("com.mysql.jdbc.Driver");
				con = (Connection) DriverManager.getConnection("jdbc:mysql://localhost:3306/QueryCorrector","root","");
			}	
			catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			}
	}
	
	private void loadDataBase() throws SQLException
	{
		ArrayList<Word> palabras = new ArrayList<Word>();
		
		//Cargamos las palabras del diccionario, creando un objeto "word" con sus n-gramas para cada una	
		FileDataSource diccionario = null;
		try {
			diccionario = new FileDataSource(filename);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
			//Cargamos la base de datos con las palabras y los n-gramas de la longitud establecida.
			while(!diccionario.hasDataLeft()){		
				try{
				palabras.add(new Word(diccionario.getNextWord(),ngramLength));
				}
				catch (DomainException e) {
					continue;
				}
			}
		

		for(Word w:palabras){
			for(Ngramm s:w.getNgramms()){
				Statement st = (Statement) con.createStatement();
				st.execute("insert into palabra values ('"+s.getValue()+"','" + w.getValue() + "')");
			}
		}
	}
	
	public ArrayList<String> getWordsWithSameNGramms(String wordToCorrect)
	{
		ArrayList<String> wordsWithSameNGrams = new ArrayList<String>();
		Word wordACorregir = null;
		try {
			wordACorregir = new Word(wordToCorrect, ngramLength);
		} catch (DomainException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}		
		ArrayList<String> palabrasAEvaluar = new ArrayList<String>();
		TreeSet resultados = new TreeSet(); 
		HashMap resMap = new HashMap();
		CommonCoeficientCalculationWithPositionStrategy coeficiente = new CommonCoeficientCalculationWithPositionStrategy();
		
		//Para cada n-grama, busco las palabras que contengan el mismo n-grama y calculo el coeficiente respecto a mi palabra a corregir,
		//Me quedo con el máximo coeficiente
		for(Ngramm s:wordACorregir.getNgramms()){
			Statement st = null;
			try {
				st = (Statement) con.createStatement();
				ResultSet result = null;			
				result = st.executeQuery("select palabra from palabra where ngram = '" + s.getValue() +"'");
				while(result.next())
				{
					wordsWithSameNGrams.add(result.getString(1));
				}
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}		
		return wordsWithSameNGrams;
	}
	
}
